package com.platform.core.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import com.platform.comm.dto.DtoMapper;
import com.platform.comm.service.impl.CommonBizImpl;
import com.platform.core.entity.CdJxcManageEntity;
import com.platform.core.entity.CdProductManageEntity;
import com.platform.core.entity.QCdJxcManageEntity;
import com.platform.core.repository.CdJxcManageRepository;
import com.platform.core.service.CdComManageBiz;
import com.platform.core.service.CdJxcManageBiz;
import com.platform.core.service.CdProductManageBiz;
import com.platform.dto.CdComManageDto;
import com.platform.dto.CdJxcManageDto;
import com.platform.dto.CdJxcManageProd;
import com.platform.dto.CdProductManageDto;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QSort;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * Description: CdJxcManage-业务接口实现类
 *
 * @author Coder
 */
@Slf4j
@Service
public class CdJxcManageBizImpl extends CommonBizImpl<CdJxcManageRepository, CdJxcManageEntity, String> implements CdJxcManageBiz {

    private final QCdJxcManageEntity qCdJxcManage = QCdJxcManageEntity.cdJxcManageEntity;
    private final DtoMapper mapper;
    private final CdProductManageBiz cdProductManageBiz;
    private final CdComManageBiz cdComManageBiz;

    @Autowired
    public JdbcTemplate jdbcTemplate;

    @Autowired
    private EntityManager entityManager;

    public CdJxcManageBizImpl(CdJxcManageRepository cdJxcManageRepository, DtoMapper mapper,
                              CdProductManageBiz cdProductManageBiz, CdComManageBiz cdComManageBiz) {
        super(cdJxcManageRepository);
        this.mapper = mapper;
        this.cdProductManageBiz = cdProductManageBiz;
        this.cdComManageBiz = cdComManageBiz;
    }

    @Override
    public Page<CdJxcManageDto> search(Map<String, String> params, Pageable pageable) {
        BooleanBuilder builder = new BooleanBuilder();
        String productName = MapUtil.getStr(params, "productName");
        String comId = MapUtil.getStr(params, "comId");
        String operateName = MapUtil.getStr(params, "operateName");
        String category = MapUtil.getStr(params, "category");
        String outandin = MapUtil.getStr(params, "outandin");
        String operateDate = MapUtil.getStr(params, "operateDate");
        if (StringUtils.isNotEmpty(productName)) {
            builder.and(qCdJxcManage.productName.contains(productName));
        }
        if (StringUtils.isNotEmpty(operateName)) {
            builder.and(qCdJxcManage.operateName.contains(operateName));
        }
        if (StringUtils.isNotEmpty(category)) {
            builder.and(qCdJxcManage.category.eq(category));
        }
        if (StringUtils.isNotEmpty(outandin)) {
            builder.and(qCdJxcManage.outandin.eq(outandin));
        }
        if (StringUtils.isNotEmpty(operateDate)) {
            builder.and(qCdJxcManage.operateDate.eq(LocalDate.parse(operateDate)));
        }
        if (StringUtils.isNotEmpty(comId)) {
            builder.and(qCdJxcManage.comId.eq(comId));
        }
        if (pageable.getSort().isUnsorted()) {
            pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), QSort.by(qCdJxcManage.createDate.desc()));
        }
        Page<CdJxcManageEntity> page = queryByPage(builder, pageable);

        return page.map(entity -> {
            CdJxcManageDto map = mapper.map(entity, CdJxcManageDto.class);
            if (StringUtils.equals(map.getOutandin(), "0")) {
                map.setCount(map.getCount() * (-1));
            }
            return map;
        });
    }

    @Override
    public List<CdJxcManageDto> jxcSearch(CdJxcManageDto dto) {
        List<CdJxcManageDto> d = Lists.newArrayList();
        String category = dto.getCategory();
        String coating = dto.getCoating();
        String comId = dto.getComId();
        String color = dto.getColor();
        String productName = dto.getProductName();
        BooleanBuilder builder = new BooleanBuilder();
        StringBuilder whereSql = new StringBuilder();
        if (StringUtils.isNotEmpty(category)) {
            if (StringUtils.isNotEmpty(whereSql)) {
                whereSql.append("and category = '").append(category).append("'");
            } else {
                whereSql.append("category = '").append(category).append("'");
            }
        }
        if (StringUtils.isNotEmpty(coating)) {
            if (StringUtils.isNotEmpty(whereSql)) {
                whereSql.append("and coating = '").append(coating).append("'");
            } else {
                whereSql.append("coating = '").append(coating).append("'");
            }
        }
        if (StringUtils.isNotEmpty(comId)) {
            if (StringUtils.isNotEmpty(whereSql)) {
                whereSql.append("and comId = '").append(comId).append("'");
            } else {
                whereSql.append("comId = '").append(comId).append("'");
            }
        }
        if (StringUtils.isNotEmpty(color)) {
            if (StringUtils.isNotEmpty(whereSql)) {
                whereSql.append("and color = '").append(color).append("'");
            } else {
                whereSql.append("color = '").append(color).append("'");
            }
        }
        if (StringUtils.isNotEmpty(productName)) {
            if (StringUtils.isNotEmpty(whereSql)) {
                whereSql.append("and product_name like '%").append(productName).append("%'");
            } else {
                whereSql.append("product_name like '%").append(productName).append("%'");
            }
        }
        String querySql = "";
        if (StringUtils.isEmpty(whereSql.toString())) {
            querySql = "select comId,product_id as productId,SUM(count) as totalCount from cd_jxc_manage group by comId ,product_id";
        } else {
            querySql = "select comId,product_id as productId,SUM(count) as totalCount from cd_jxc_manage where " + whereSql.toString() + "group by comId ,product_id";
        }
        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(querySql);
        if (CollectionUtil.isNotEmpty(mapList)) {
            mapList.forEach(item -> {
                String comId2 = item.get("comId").toString();
                String productId2 = item.get("productId").toString();
                long totalCount = Integer.parseInt(item.get("totalCount").toString());
                CdComManageDto comDetail = cdComManageBiz.detail(comId2);
                CdProductManageDto productDetail = cdProductManageBiz.detail(productId2);
                CdJxcManageDto result = new CdJxcManageDto();
                result.setSpecification(productDetail.getSpecification());
                result.setCategory(productDetail.getCategory());
                result.setCoating(productDetail.getCoating());
                result.setColor(productDetail.getColor());
                result.setProductId(productDetail.getId());
                result.setProductName(productDetail.getProductName());
                result.setCount(totalCount);
                result.setComId(comDetail.getId());
                result.setComName(comDetail.getComName());
                d.add(result);
            });
        }
        return d;
    }

    @Override
    public CdJxcManageDto detail(String id) {
        return mapper.map(fetchById(id), CdJxcManageDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(CdJxcManageDto req) {
        CdJxcManageEntity entity = mapper.map(req, CdJxcManageEntity.class);
        if (StringUtils.equals(entity.getOutandin(), "0")) {
            entity.setCount(req.getCount() * (-1));
        }
        CdProductManageDto detail = cdProductManageBiz.detail(entity.getProductId());
        entity.setProductName(detail.getProductName());
        entity.setColor(detail.getColor());
        entity.setCoating(detail.getCoating());
        entity.setCategory(detail.getCategory());
        entity.setSpecification(detail.getSpecification());
        entity.setCreateDate(LocalDateTime.now());
        saveEntity(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchCreate(CdJxcManageProd req) {
        List<CdJxcManageDto> jxcManages = req.getJxcManages();
        String comId = req.getComId();
        String category = req.getCategory();
        String outandin = req.getOutandin();
        String operateName = req.getOperateName();
        String operateDate = req.getOperateDate();
        List<CdJxcManageEntity> objects = Lists.newArrayList();
        if (CollectionUtil.isNotEmpty(jxcManages)) {
            jxcManages.forEach(item -> {
                CdJxcManageEntity entity = mapper.map(item, CdJxcManageEntity.class);
                CdProductManageDto detail = cdProductManageBiz.detail(entity.getProductId());
                entity.setComId(comId);
                entity.setOutandin(outandin);
                entity.setProductName(detail.getProductName());
                entity.setColor(detail.getColor());
                entity.setCoating(detail.getCoating());
                entity.setCategory(detail.getCategory());
                entity.setSpecification(detail.getSpecification());
                entity.setCreateDate(LocalDateTime.now());
                entity.setOperateName(operateName);
                entity.setOperateDate(LocalDate.parse(operateDate));
                if (StringUtils.equals(outandin, "0")) {
                    entity.setCount(entity.getCount() * (-1));
                }
                objects.add(entity);
                repository.saveAll(objects);
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modify(CdJxcManageDto req) {
        CdJxcManageEntity entity = fetchById(req.getId());
        CdProductManageDto detail = cdProductManageBiz.detail(entity.getProductId());
        entity.setColor(detail.getColor());
        entity.setCoating(detail.getCoating());
        entity.setCategory(detail.getCategory());
        entity.setSpecification(detail.getSpecification());
        entity.setCreateDate(LocalDateTime.now());
        mapper.map(req, entity);
        saveEntity(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(String id) {
        repository.deleteById(id);
    }
}
